package top.zsyle.pet.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import top.zsyle.basic.jwt.UserInfo;
import top.zsyle.basic.util.*;
import top.zsyle.order.domain.OrderPetAcquisition;
import top.zsyle.order.mapper.OrderPetAcquisitionMapper;
import top.zsyle.org.domain.Shop;
import top.zsyle.org.mapper.ShopMapper;
import top.zsyle.pet.domain.Pet;
import top.zsyle.pet.domain.SearchMasterMsg;
import top.zsyle.pet.domain.SearchMasterMsgAuditLog;
import top.zsyle.pet.dto.AcceptDto;
import top.zsyle.pet.dto.SearchMsgPublishDto;
import top.zsyle.pet.mapper.PetMapper;
import top.zsyle.pet.mapper.SearchMasterMsgAuditLogMapper;
import top.zsyle.pet.mapper.SearchMasterMsgMapper;
import top.zsyle.pet.query.SearchMasterMsgQuery;
import top.zsyle.pet.service.ISearchMasterMsgService;
import top.zsyle.basic.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import top.zsyle.user.domain.User;
import top.zsyle.user.mapper.UserMapper;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zsy
 * @since 2022-12-07
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {

    @Autowired
    private SearchMasterMsgAuditLogMapper auditLogMapper;

    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;

    @Autowired
    private OrderPetAcquisitionMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private PetMapper petMapper;

    /**
     * 发布寻主
     * @param dto
     */
    @Override
    public void publish(SearchMsgPublishDto dto) {
        //1.校验参数
        //2.保存数据
        SearchMasterMsg msg = saveMsg(dto);
        //3.百度ai审核
        StringBuilder sb = new StringBuilder();
        //将name,title,coatColor,address拼接到一起审核
        SearchMasterMsgAuditLog auditLog = new SearchMasterMsgAuditLog();
        sb.append(dto.getName()).append(dto.getTitle()).append(dto.getCoatColor()).append(dto.getAddress());
        if (!BaiduAuditUtils.TextCensor(sb.toString())){
            //3.1 审核失败，state=2,添加审核日志，发送审核失败的邮件即具体信息
            auditLog.setNote("宠物文本类审核失败，宠物信息不合规："+sb.toString());
            msg.setState(2);
            // todo 发送审核失败和具体信
        }else {
            //3.2 审核成功，设置状态 state=1，审核人，添加审核日志
            auditLog.setNote("宠物文本类审核成功，宠物名称："+dto.getName());
            msg.setState(1);
            //4. 50公里以内的店铺发送寻主信息
            sendMsgToShop(dto, msg);
        }
        //设置公共部分审核信息
        setAuditLog(msg, auditLog);
        auditLogMapper.add(auditLog);
        //更新msg状态和shopId
        super.update(msg);
        //4.2 50公里没有店铺，将信息放到寻主池中
    }

    /**
     * 拒单
     * @param id
     */
    @Override
    public void reject(Long id) {
        //将shopId置空 放入寻主池
        SearchMasterMsg msg = new SearchMasterMsg();
        msg.setId(id);
        msg.setShopId(null);
        msg.setState(1);
        searchMasterMsgMapper.updateShopIdNull(msg);
        //todo 添加日志，给该店铺减分，减少寻主信息的派送
    }

    /**
     * 创建订单，接收寻主
     * @param dto
     */
    @Override
    public void accept(AcceptDto dto) {
        SearchMasterMsg msg = findById(dto.getMsgId());
        //1.生成宠物信息
        Pet pet = new Pet();
        pet.setName(msg.getName());
        pet.setState(0);
        pet.setCostprice(BigDecimal.valueOf(msg.getPrice()));
        pet.setSearchMasterMsgId(msg.getId());
        pet.setTypeId(msg.getPetType());
        pet.setShopId(msg.getShopId());
        pet.setCreatetime(new Date());
        petMapper.add(pet);
        //2.生成收购单
        OrderPetAcquisition order = new OrderPetAcquisition();
        order.setOrderSn(CodeGenerateUtils.generateOrderSn(msg.getUserId()));
        order.setDigest("xxxx接了单");
        order.setLastConfirmTime(new Date(System.currentTimeMillis() + 2*24*60*60*1000));
        order.setState(0);
        order.setPrice(BigDecimal.valueOf(msg.getPrice()));
        order.setPayType(1);
        order.setPaySn(UUID.randomUUID().toString());
        order.setAddress(msg.getAddress());
        order.setPetId(pet.getId());
        order.setUserId(msg.getUserId());
        order.setShopId(msg.getShopId());
        order.setEmpId(dto.getHandler());
        order.setMsgId(msg.getId());
        orderMapper.add(order);
        // 3.msg的状态改成已接单
        SearchMasterMsg m = new SearchMasterMsg();
        m.setId(msg.getId());
        m.setState(3);
        m.setShopId(msg.getShopId());
        searchMasterMsgMapper.update(m);
    }


    /**
     * 保存信息
     * @param dto
     * @return
     */
    private SearchMasterMsg saveMsg(SearchMsgPublishDto dto) {
        SearchMasterMsg msg = new SearchMasterMsg();
        BeanUtils.copyProperties(dto,msg);
        //获取当前卖方用户Id
//        UserInfo userInfo = ThreadLocalUtil.getUserInfo();
        UserInfo userInfo = LoginContext.getUserInfo();
        User user = userMapper.findByLogininfoId(userInfo.getLogininfo().getId());
        if (null != user){
            msg.setUserId(user.getId());
        }
        //设置默认状态为  0 待审核
        msg.setState(0);
        super.add(msg);
        return msg;
    }

    /**
     * 给 mes绑定shopId
     * @param dto
     * @param msg
     */
    private void sendMsgToShop(SearchMsgPublishDto dto, SearchMasterMsg msg) {
        Point point = DistanceUtil.getPoint(dto.getAddress());
        List<Shop> shops = shopMapper.findAll();
        if (null != point && null != shops){
            Shop nearestShop = DistanceUtil.getNearestShop(point, shops);
            if (null != nearestShop){
                //4.1 有店铺，给最近的店铺发送寻主信息，并给寻主信息绑定 shipId
                msg.setShopId(nearestShop.getId());
            }
        }
    }


    //设置公共部分审核日志
    private void setAuditLog(SearchMasterMsg msg, SearchMasterMsgAuditLog auditLog) {
        //msgId
        auditLog.setMsgId(msg.getId());
        //审核时间
        auditLog.setAuditTime(new Date());
        //系统审核，默认-1L
        auditLog.setAuditId(-1L);
        //默认 1
        auditLog.setState(1);
    }
}
